# 安装实验室使用的特定版本库（注释掉的安装命令）
#! mamba install pandas==1.3.3  # 安装pandas 1.3.3版本
#! mamba install numpy=1.21.2   # 安装numpy 1.21.2版本
#! mamba install scipy=1.7.1-y  # 安装scipy 1.7.1版本
#!  mamba install seaborn=0.9.0-y  # 安装seaborn 0.9.0版本
# 导入必要的Python库
import pandas as pd  # 用于数据处理和分析
import numpy as np   # 用于数值计算
import matplotlib.pyplot as plt  # 用于数据可视化
import seaborn as sns  # 基于matplotlib的高级数据可视化库
# 定义数据文件路径（在线CSV文件）
filepath='https://cf-courses-data.s3.us.cloud-object-storage.appdomain.cloud/IBMDeveloperSkillsNetwork-DA0101EN-SkillsNetwork/labs/Data%20files/automobileEDA.csv'

# 问题分析：使用 header=None 导致第一行（列名）被当作数据行
# 第一行包含字符串 "symboling"，导致整列被推断为 object 类型
# 解决方案：移除 header=None 参数，让 pandas 正确识别表头

# 读取CSV文件数据到DataFrame
df = pd.read_csv(filepath)  # 移除 header=None 参数，让pandas自动识别表头

# 显示数据的前5行，查看数据结构
print(df.head())

# 显示每列的数据类型
print(df.dtypes)

# 选择数值型列（浮点型和整型）
numeric_df = df.select_dtypes(include=['float64', 'int64'])
# 计算数值列之间的相关系数矩阵
print(numeric_df.corr())
# 计算特定列之间的相关系数
print(df[['bore', 'stroke', 'compression-ratio', 'horsepower']].corr())
# 创建发动机尺寸与价格的回归图
sns.regplot(x="engine-size", y="price", data=df)  # 绘制回归线图
plt.ylim(0,)  # 设置y轴从0开始
plt.show()  # 显示图形
# 创建车身样式与价格的箱线图
sns.boxplot(x="body-style", y="price", data=df)  # 绘制箱线图
plt.show()  # 显示图形
# 显示数值型列的统计摘要（计数、均值、标准差、最小值、四分位数、最大值）
print(df.describe())
# 显示对象类型列（字符串列）的统计摘要
print(df.describe(include=['object']))
# 统计驱动轮类型的频数分布
print(df['drive-wheels'].value_counts())
# 将驱动轮频数统计转换为DataFrame格式
drive_wheels_counts = df['drive-wheels'].value_counts().to_frame()

# 重置索引，将索引转换为列
drive_wheels_counts.reset_index(inplace=True)
# 重命名列名，使含义更清晰
drive_wheels_counts=drive_wheels_counts.rename(columns={'drive-wheels': 'value_counts'})
# 设置索引名称
drive_wheels_counts.index.name = 'drive-wheels'
# 显示驱动轮频数统计结果
print(drive_wheels_counts)
# 选择驱动轮、车身样式和价格列用于分组分析
df_group_one = df[['drive-wheels','body-style','price']]
# 按驱动轮分组，计算每组的平均价格
df_grouped = df_group_one.groupby(['drive-wheels'], as_index=False).agg({'price': 'mean'})
# 显示按驱动轮分组的平均价格
print(df_grouped)
# 选择驱动轮、车身样式和价格列用于更详细的分组分析
df_gptest = df[['drive-wheels','body-style','price']]
# 按驱动轮和车身样式双重分组，计算每组的平均价格
grouped_test1 = df_gptest.groupby(['drive-wheels','body-style'],as_index=False).mean()
# 显示双重分组后的平均价格结果
print(grouped_test1)
# 将分组数据转换为透视表格式，便于热图可视化
grouped_pivot = grouped_test1.pivot(index='drive-wheels',columns='body-style')
# 显示透视表
print(grouped_pivot)
# 用0填充透视表中的缺失值并显示
print(grouped_pivot.fillna(0))    
# 选择车身样式和价格列用于单变量分组分析
df_gptest2 = df[['body-style','price']]
# 按车身样式分组，计算每组的平均价格
grouped_test_bodystyle = df_gptest2.groupby(['body-style'],as_index= False).mean()
# 显示按车身样式分组的平均价格
print(grouped_test_bodystyle)
# 使用pcolor函数创建热图，显示驱动轮和车身样式组合的平均价格
plt.pcolor(grouped_pivot, cmap='RdBu')  # 使用红蓝配色方案
plt.colorbar()  # 添加颜色条
plt.show()  # 显示图形
# 使用pivot_table函数创建热图数据，计算驱动轮和车身样式组合的平均价格
heatmap_data = pd.pivot_table(df, 
                             values='price',  # 聚合的值列
                             index='drive-wheels',  # 行索引
                             columns='body-style',  # 列索引
                             aggfunc='mean')  # 聚合函数为平均值
# 使用seaborn创建热图可视化
sns.heatmap(heatmap_data, cmap='RdBu')  # 使用红蓝配色方案的热图
plt.show()  # 显示图形
# 创建自定义热图，添加轴标签和格式化
fig, ax = plt.subplots()  # 创建图形和坐标轴对象
im = ax.pcolor(grouped_pivot, cmap='RdBu')  # 在坐标轴上绘制热图

# 获取行标签和列标签
row_labels = grouped_pivot.columns.levels[1]  # 获取车身样式标签（第二级列索引）
col_labels = grouped_pivot.index  # 获取驱动轮标签

# 设置x轴和y轴的刻度位置
ax.set_xticks(np.arange(grouped_pivot.shape[1]) + 0.5, minor=False)  # x轴刻度位置
ax.set_yticks(np.arange(grouped_pivot.shape[0]) + 0.5, minor=False)  # y轴刻度位置

# 设置x轴和y轴的刻度标签
ax.set_xticklabels(row_labels, minor=False)  # x轴标签为车身样式
ax.set_yticklabels(col_labels, minor=False)  # y轴标签为驱动轮类型

# 旋转x轴标签90度，避免重叠
plt.xticks(rotation=90)

# 添加颜色条并显示最终图形
fig.colorbar(im)  # 为热图添加颜色条
plt.show()  # 显示完整的自定义热图
